package com.base.git;

import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.LogCommand;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.springframework.util.StringUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * git命令
 */
public class GitCommandUtils {


    private List<String> getBranchList(String remoteUrl,String username,
                                       String password,String localPath) throws Exception {
        List<String> branchList = new ArrayList<>();
        Git git = getGit(remoteUrl, username, password, localPath);
        Repository repository = git.getRepository();
        List<Ref> refs = repository.getRefDatabase().getRefs();
        for (Ref head : refs) {
            branchList.add(head.getName());
        }
        git.close();
        repository.close();
        deleteFolder(new File(localPath));
        return branchList;
    }


    private List<String> getHistoryList(String remoteUrl,String username,String password,
                                        String localPath,String branch) throws Exception {
        List<String> historyList = new ArrayList<>();
        Git git = getGit(remoteUrl, username, password, localPath);
        Repository repository = git.getRepository();
        List<Ref> refs = repository.getRefDatabase().getRefs();
        for (Ref head : refs) {
            String name = head.getName();
            if (!StringUtils.isEmpty(branch) && !name.equals(branch)) {
                continue;
            }
            ObjectId branchId = head.getObjectId();
            LogCommand logCommand = Git.wrap(repository).log().add(branchId);
            Iterable<RevCommit> commits = logCommand.call();
            for (RevCommit commit : commits) {
                historyList.add(commit.getFullMessage());
            }
        }
        git.close();
        repository.close();
        deleteFolder(new File(localPath));
        return historyList;
    }

    public void commit(String localPath,String authorName,
                       String authorEmail,String message) throws Exception {
        Repository repository = new FileRepositoryBuilder()
                .setGitDir(new File(localPath + "/.git"))
                .build();
        Git git = new Git(repository);
        // git.add().addFilepattern(".").call();
        CommitCommand commitCommand = git.commit();
        commitCommand.setAuthor(authorName, authorEmail);
        commitCommand.setMessage(message);

        commitCommand.call();
        git.close();
        repository.close();
    }

    private void push(String remoteUrl,String username,
                      String password,String localPath) throws Exception {

        Repository repository = Git.open(new File(localPath)).getRepository();
        Git git = new Git(repository);
        URIish uri = new URIish(remoteUrl);
        PushCommand pushCmd = git.push();
        pushCmd.setRemote(uri.toASCIIString());
        pushCmd.setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password));
        // 执行 push
        Iterable<PushResult> results = pushCmd.call();
        // 处理 push 结果
        for (PushResult result : results) {
            System.out.println(result.getRemoteUpdates());
            result.getRemoteUpdates().forEach(item -> {
                if (item.getStatus() == RemoteRefUpdate.Status.OK) {
                    System.out.println("Push successful!");
                } else {
                    System.out.println("Push failed: " + item.getStatus());
                }
            });
        }
        git.close();
        repository.close();
    }


    private Git getGit(String remoteUrl,String username,
                       String password,String localPath) throws Exception {
        Git git = Git.cloneRepository()
                .setURI(remoteUrl)
                .setDirectory(new File(localPath)) // 临时目录用于存储 Git 仓库
                .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password))
                .call();
        return git;
    }

    public static void deleteFolder(File folder) {
        if (folder.isDirectory()) {
            File[] files = folder.listFiles();
            if (files != null) {
                for (File file : files) {
                    deleteFolder(file);
                }
            }
        }
        folder.delete();
    }

}
